{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化智谱 embedding\n",
    "from typing import Any, Dict, List, Optional\n",
    "\n",
    "from langchain_core.embeddings import Embeddings\n",
    "from langchain_core.utils import get_from_dict_or_env\n",
    "from pydantic import BaseModel, Field, model_validator\n",
    "import os\n",
    "from zhipuai import ZhipuAI\n",
    "\n",
    "class ZhipuAIEmbeddings(BaseModel, Embeddings):\n",
    "    \"\"\"ZhipuAI embedding model integration.\n",
    "\n",
    "    Setup:\n",
    "\n",
    "        To use, you should have the ``zhipuai`` python package installed, and the\n",
    "        environment variable ``ZHIPU_API_KEY`` set with your API KEY.\n",
    "\n",
    "        More instructions about ZhipuAi Embeddings, you can get it\n",
    "        from  https://open.bigmodel.cn/dev/api#vector\n",
    "\n",
    "        .. code-block:: bash\n",
    "\n",
    "            pip install -U zhipuai\n",
    "            export ZHIPU_API_KEY=\"your-api-key\"\n",
    "\n",
    "    Key init args — completion params:\n",
    "        model: Optional[str]\n",
    "            Name of ZhipuAI model to use.\n",
    "        api_key: str\n",
    "            Automatically inferred from env var `ZHIPU_API_KEY` if not provided.\n",
    "\n",
    "    See full list of supported init args and their descriptions in the params section.\n",
    "\n",
    "    Instantiate:\n",
    "\n",
    "        .. code-block:: python\n",
    "\n",
    "            from langchain_community.embeddings import ZhipuAIEmbeddings\n",
    "\n",
    "            embed = ZhipuAIEmbeddings(\n",
    "                model=\"embedding-2\",\n",
    "                # api_key=\"...\",\n",
    "            )\n",
    "\n",
    "    Embed single text:\n",
    "        .. code-block:: python\n",
    "\n",
    "            input_text = \"The meaning of life is 42\"\n",
    "            embed.embed_query(input_text)\n",
    "\n",
    "        .. code-block:: python\n",
    "\n",
    "            [-0.003832892, 0.049372625, -0.035413884, -0.019301128, 0.0068899863, 0.01248398, -0.022153955, 0.006623926, 0.00778216, 0.009558191, ...]\n",
    "\n",
    "\n",
    "    Embed multiple text:\n",
    "        .. code-block:: python\n",
    "\n",
    "            input_texts = [\"This is a test query1.\", \"This is a test query2.\"]\n",
    "            embed.embed_documents(input_texts)\n",
    "\n",
    "        .. code-block:: python\n",
    "\n",
    "            [\n",
    "                [0.0083934665, 0.037985895, -0.06684559, -0.039616987, 0.015481004, -0.023952313, ...],\n",
    "                [-0.02713102, -0.005470169, 0.032321047, 0.042484466, 0.023290444, 0.02170547, ...]\n",
    "            ]\n",
    "    \"\"\"  # noqa: E501\n",
    "\n",
    "    client: Any = Field(default=None, exclude=True)  #: :meta private:\n",
    "    model: str = Field(default=\"embedding-2\")\n",
    "    \"\"\"Model name\"\"\"\n",
    "    api_key: str\n",
    "    \"\"\"Automatically inferred from env var `ZHIPU_API_KEY` if not provided.\"\"\"\n",
    "    dimensions: Optional[int] = None\n",
    "    \"\"\"The number of dimensions the resulting output embeddings should have.\n",
    "\n",
    "    Only supported in `embedding-3` and later models.\n",
    "    \"\"\"\n",
    "\n",
    "    @model_validator(mode=\"before\")\n",
    "    @classmethod\n",
    "    def validate_environment(cls, values: Dict) -> Any:\n",
    "        \"\"\"Validate that auth token exists in environment.\"\"\"\n",
    "        values[\"api_key\"] = get_from_dict_or_env(values, \"api_key\", \"ZHIPUAI_API_KEY\")\n",
    "        try:\n",
    "            from zhipuai import ZhipuAI\n",
    "\n",
    "            values[\"client\"] = ZhipuAI(api_key=values[\"api_key\"])\n",
    "        except ImportError:\n",
    "            raise ImportError(\n",
    "                \"Could not import zhipuai python package.\"\n",
    "                \"Please install it with `pip install zhipuai`.\"\n",
    "            )\n",
    "        return values\n",
    "\n",
    "\n",
    "\n",
    "    def embed_query(self, text: str) -> List[float]:\n",
    "        \"\"\"\n",
    "        Embeds a text using the AutoVOT algorithm.\n",
    "\n",
    "        Args:\n",
    "            text: A text to embed.\n",
    "\n",
    "        Returns:\n",
    "            Input document's embedded list.\n",
    "        \"\"\"\n",
    "        resp = self.embed_documents([text])\n",
    "        return resp[0]\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "    def embed_documents(self, texts: List[str]) -> List[List[float]]:\n",
    "        \"\"\"\n",
    "        Embeds a list of text documents using the AutoVOT algorithm.\n",
    "\n",
    "        Args:\n",
    "            texts: A list of text documents to embed.\n",
    "\n",
    "        Returns:\n",
    "            A list of embeddings for each document in the input list.\n",
    "            Each embedding is represented as a list of float values.\n",
    "        \"\"\"\n",
    "        if self.dimensions is not None:\n",
    "            resp = self.client.embeddings.create(\n",
    "                model=self.model,\n",
    "                input=texts,\n",
    "                dimensions=self.dimensions,\n",
    "            )\n",
    "        else:\n",
    "            resp = self.client.embeddings.create(model=self.model, input=texts)\n",
    "        embeddings = [r.embedding for r in resp.data]\n",
    "        return embeddings\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from pprint import pprint\n",
    "import chromadb\n",
    "from langchain.llms import Tongyi\n",
    "from langchain.schema import Document\n",
    "from langchain.chains import RetrievalQA\n",
    "from langchain.vectorstores import Chroma\n",
    "\n",
    "# 载入环境变量\n",
    "load_dotenv()\n",
    "\n",
    "# 1. 定义嵌入函数（使用预训练的嵌入模型）\n",
    "embedding = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n",
    "# 2. 初始化 Chroma 向量存储（使用 LangChain 的 Chroma 类）\n",
    "persist_directory = \"ch16_db\"  # 与您之前使用的路径保持一致\n",
    "vectorstore = Chroma(\n",
    "    persist_directory=persist_directory,\n",
    "    embedding_function=embedding,\n",
    "    collection_name=\"products\"\n",
    ")\n",
    "\n",
    "# 3. 准备要添加的文档和元数据\n",
    "documents = [\"Galaxy S21\", \"iPhone 13\", \"MacBook Pro\"]\n",
    "metadatas = [\n",
    "    {\"category\": \"手机\", \"price\": 799.99},\n",
    "    {\"category\": \"手机\", \"price\": 999.99},\n",
    "    {\"category\": \"笔记本电脑\", \"price\": 1299.99}\n",
    "]\n",
    "ids = [\"prod1\", \"prod2\", \"prod3\"]\n",
    "\n",
    "# 4. 将文档和元数据转换为 LangChain 的 Document 对象\n",
    "document_objects = [Document(page_content=doc, metadata=meta) for doc, meta in zip(documents, metadatas)]\n",
    "\n",
    "# 5. 添加文档到 Chroma 向量存储中\n",
    "vectorstore.add_documents(documents=document_objects, ids=ids)\n",
    "\n",
    "print(\"数据添加完成！\")\n",
    "\n",
    "# 6. 获取集合中的所有数据\n",
    "all_data = vectorstore._collection.get()\n",
    "print(\"集合中的所有数据：\")\n",
    "pprint(all_data)\n",
    "\n",
    "# 7. 根据 ID 获取特定的文档\n",
    "specific_data = vectorstore._collection.get(ids=[\"prod1\"])\n",
    "print(\"\\nID 为 'prod1' 的文档：\")\n",
    "pprint(specific_data)\n",
    "\n",
    "# 8. 根据元数据条件获取文档\n",
    "filtered_data = vectorstore._collection.get(where={\"category\": \"手机\"})\n",
    "print(\"\\n类别为 '手机' 的文档：\")\n",
    "pprint(filtered_data)\n",
    "\n",
    "# 9. 更新已有文档的元数据\n",
    "vectorstore._collection.update(\n",
    "    ids=[\"prod1\"],\n",
    "    metadatas=[{\"category\": \"手机\", \"price\": 749.99}]\n",
    ")\n",
    "print(\"\\n已更新 ID 为 'prod1' 的文档价格。\")\n",
    "\n",
    "# 10. 删除特定 ID 的文档\n",
    "vectorstore._collection.delete(ids=[\"prod2\"])\n",
    "print(\"\\n已删除 ID 为 'prod2' 的文档。\")\n",
    "\n",
    "# 11. 查看集合中剩余的文档\n",
    "remaining_data = vectorstore._collection.get()\n",
    "print(\"\\n剩余的文档：\")\n",
    "pprint(remaining_data)\n",
    "\n",
    "# 12. 初始化 Tongyi 语言模型\n",
    "llm = Tongyi(\n",
    "    model='qwen-plus',  # 替换为您使用的 Tongyi 模型名称\n",
    "    top_p=0.9,\n",
    "    temperature=0.9,\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\")\n",
    ")\n",
    "\n",
    "# 13. 创建检索器（Retriever）\n",
    "retriever = vectorstore.as_retriever()\n",
    "\n",
    "# 14. 创建 RetrievalQA 链\n",
    "qa = RetrievalQA.from_chain_type(\n",
    "    llm=llm,\n",
    "    chain_type=\"stuff\",  # \"stuff\" 是一种简单的链类型，您可以根据需要选择其他类型\n",
    "    retriever=retriever,\n",
    "    return_source_documents=True\n",
    ")\n",
    "\n",
    "# 15. 执行简单查询（方法一）\n",
    "query = \"苹果手机\"\n",
    "result = qa({\"query\": query})\n",
    "print(\"\\n简单查询结果：\")\n",
    "print(result[\"result\"])\n",
    "\n",
    "# 如果您不需要来源文档，可以在创建 qa 对象时将 return_source_documents 设置为 False：\n",
    "qa = RetrievalQA.from_chain_type(\n",
    "    llm=llm,\n",
    "    chain_type=\"stuff\",\n",
    "    retriever=retriever,\n",
    "    return_source_documents=False\n",
    ")\n",
    "# 然后可以使用 qa.run(query) 方法：\n",
    "result = qa.run(query)\n",
    "print(\"\\n简单查询结果：\")\n",
    "print(result)\n",
    "\n",
    "# 16. 执行带来源的查询\n",
    "result_with_sources = qa({\"query\": query})\n",
    "print(\"\\n带来源的查询结果：\")\n",
    "pprint(result_with_sources)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from langchain.indexes import VectorstoreIndexCreator\n",
    "from langchain.document_loaders import TextLoader\n",
    "from langchain.chains import RetrievalQA\n",
    "from langchain.vectorstores import Chroma\n",
    "from langchain.llms import Tongyi  # 或者其他语言模型，例如 Tongyi\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "\n",
    "\n",
    "# 1. 定义嵌入函数（使用预训练的嵌入模型）\n",
    "embedding = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n",
    "# 2. 初始化 Chroma 向量存储（使用 LangChain 的 Chroma 类）\n",
    "persist_directory = \"ch16_db\"  # 与您之前使用的路径保持一致\n",
    "vectorstore = Chroma(\n",
    "    persist_directory=persist_directory,\n",
    "    embedding_function=embedding,\n",
    "    collection_name=\"products\"\n",
    ")\n",
    "# 1. 加载文档\n",
    "loader = TextLoader('/root/autodl-tmp/lizhenping/langchain_tutorial/LangChain_CookBook/data/市场分析报告.txt', encoding='utf-8')\n",
    "documents = loader.load()\n",
    "\n",
    "# 2. 创建向量存储索引\n",
    "index_creator = VectorstoreIndexCreator(\n",
    "    vectorstore_cls=Chroma,\n",
    "    embedding=embedding,  # 替换为您使用的嵌入模型实例\n",
    ")\n",
    "index = index_creator.from_loaders([loader])\n",
    "\n",
    "# 3. 执行简单查询\n",
    "query = \"这篇文章的主要内容是什么？\"\n",
    "response = index.query(query)\n",
    "print(\"简单查询结果：\")\n",
    "print(response)\n",
    "\n",
    "\n",
    "llm = Tongyi(\n",
    "    model='qwen-plus',  # 替换为您使用的 Tongyi 模型名称\n",
    "    top_p=0.9,\n",
    "    temperature=0.9,\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\")\n",
    ")\n",
    "\n",
    "retriever = index.vectorstore.as_retriever()\n",
    "qa_chain = RetrievalQA.from_chain_type(\n",
    "    llm=llm,\n",
    "    chain_type=\"stuff\",  # 您可以根据需要选择其他链类型\n",
    "    retriever=retriever\n",
    ")\n",
    "\n",
    "# 5. 执行高级查询\n",
    "advanced_query = \"请详细总结一下文章的关键观点。\"\n",
    "result = qa_chain.run(advanced_query)\n",
    "print(\"高级查询结果：\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from langchain.indexes import VectorstoreIndexCreator\n",
    "from langchain.document_loaders import TextLoader\n",
    "from langchain.chains import RetrievalQA\n",
    "from langchain.vectorstores import Chroma\n",
    "from langchain.llms import Tongyi  # 或者其他语言模型，例如 Tongyi\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "\n",
    "\n",
    "# 1. 定义嵌入函数（使用预训练的嵌入模型）\n",
    "embedding = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n",
    "# 2. 初始化 Chroma 向量存储（使用 LangChain 的 Chroma 类）\n",
    "persist_directory = \"ch16_db\"  # 与您之前使用的路径保持一致\n",
    "vectorstore = Chroma(\n",
    "    persist_directory=persist_directory,\n",
    "    embedding_function=embedding,\n",
    "    collection_name=\"products\"\n",
    ")\n",
    "# 1. 加载文档\n",
    "loader = TextLoader('/root/autodl-tmp/lizhenping/langchain_tutorial/LangChain_CookBook/data/市场分析报告.txt', encoding='utf-8')\n",
    "documents = loader.load()\n",
    "\n",
    "# 2. 创建向量存储索引\n",
    "index_creator = VectorstoreIndexCreator(\n",
    "    vectorstore_cls=Chroma,\n",
    "    embedding=embedding,  # 替换为您使用的嵌入模型实例\n",
    ")\n",
    "index = index_creator.from_loaders([loader])\n",
    "\n",
    "# 3. 初始化语言模型\n",
    "llm = Tongyi(\n",
    "    model='qwen-plus',  # 替换为您使用的 Tongyi 模型名称\n",
    "    top_p=0.9,\n",
    "    temperature=0.9,\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\")\n",
    ")\n",
    "# 4. 执行简单查询，提供 llm 参数\n",
    "query = \"这篇文章的主要内容是什么？\"\n",
    "response = index.query(query, llm=llm)\n",
    "print(\"简单查询结果：\")\n",
    "print(response)\n",
    "\n",
    "# 5. 创建一个检索QA链\n",
    "retriever = index.vectorstore.as_retriever()\n",
    "qa_chain = RetrievalQA.from_chain_type(\n",
    "    llm=llm,\n",
    "    chain_type=\"stuff\",  # 您可以根据需要选择其他链类型\n",
    "    retriever=retriever\n",
    ")\n",
    "\n",
    "# 6. 执行高级查询\n",
    "advanced_query = \"请详细总结一下文章的关键观点。\"\n",
    "result = qa_chain.run(advanced_query)\n",
    "print(\"高级查询结果：\")\n",
    "print(result)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from langchain.indexes import VectorstoreIndexCreator\n",
    "from langchain.document_loaders import TextLoader\n",
    "from langchain.chains import RetrievalQA\n",
    "from langchain.vectorstores import Chroma\n",
    "from langchain.llms import Tongyi  # 或者其他语言模型，例如 Tongyi\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "\n",
    "# 1. 定义嵌入函数（使用预训练的嵌入模型）\n",
    "embedding = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n",
    "# 2. 初始化 Chroma 向量存储（使用 LangChain 的 Chroma 类）\n",
    "persist_directory = \"ch16_db\"  # 与您之前使用的路径保持一致\n",
    "vectorstore = Chroma(\n",
    "    persist_directory=persist_directory,\n",
    "    embedding_function=embedding,\n",
    "    collection_name=\"products\"\n",
    ")\n",
    "# 1. 加载文档\n",
    "loader = TextLoader('/root/autodl-tmp/lizhenping/langchain_tutorial/LangChain_CookBook/data/市场分析报告.txt', encoding='utf-8')\n",
    "documents = loader.load()\n",
    "\n",
    "# 2. 创建向量存储索引\n",
    "index_creator = VectorstoreIndexCreator(\n",
    "    vectorstore_cls=Chroma,\n",
    "    embedding=embedding,  # 替换为您使用的嵌入模型实例\n",
    ")\n",
    "index = index_creator.from_loaders([loader])\n",
    "\n",
    "# 3. 获取底层的向量存储（Vectorstore）\n",
    "vectorstore = index.vectorstore\n",
    "\n",
    "# 4. 查询 Vectorstore 中的向量信息\n",
    "# 获取所有向量的 IDs\n",
    "all_ids = vectorstore._collection.get()['ids']\n",
    "print(\"所有向量的 IDs：\")\n",
    "print(all_ids)\n",
    "\n",
    "# 5. 根据 ID 获取向量和元数据\n",
    "result = vectorstore._collection.get(ids=[all_ids[0]])\n",
    "print(\"\\n获取指定 ID 的向量和元数据：\")\n",
    "print(\"IDs:\", result['ids'])\n",
    "print(\"Embeddings:\", result['embeddings'])\n",
    "print(\"Metadatas:\", result['metadatas'])\n",
    "print(\"Documents:\", result['documents'])\n",
    "\n",
    "# 6. 更新向量的元数据\n",
    "new_metadata = {\"source\": \"updated_source.txt\"}\n",
    "vectorstore._collection.update(ids=[all_ids[0]], metadatas=[new_metadata])\n",
    "print(\"\\n更新后的元数据：\")\n",
    "updated_result = vectorstore._collection.get(ids=[all_ids[0]])\n",
    "print(\"Metadatas:\", updated_result['metadatas'])\n",
    "\n",
    "# 7. 删除指定的向量\n",
    "vectorstore._collection.delete(ids=[all_ids[0]])\n",
    "print(\"\\n删除后的所有向量 IDs：\")\n",
    "print(vectorstore._collection.get()['ids'])\n",
    "\n",
    "# 8. 添加新的向量\n",
    "new_document = \"这是一个新的文档内容。\"\n",
    "new_embedding = vectorstore.embedding_function.embed_documents([new_document])[0]\n",
    "new_id = \"new_doc_id\"\n",
    "new_metadata = {\"source\": \"new_document.txt\"}\n",
    "vectorstore._collection.add(\n",
    "    ids=[new_id],\n",
    "    embeddings=[new_embedding],\n",
    "    documents=[new_document],\n",
    "    metadatas=[new_metadata]\n",
    ")\n",
    "print(\"\\n添加新向量后的所有 IDs：\")\n",
    "print(vectorstore._collection.get()['ids'])\n",
    "\n",
    "# 9. 执行相似性搜索\n",
    "query = \"查询内容\"\n",
    "query_embedding = vectorstore.embedding_function.embed_query(query)\n",
    "search_results = vectorstore._collection.query(\n",
    "    query_embeddings=[query_embedding],\n",
    "    n_results=2  # 返回最相似的 2 个结果\n",
    ")\n",
    "print(\"\\n相似性搜索结果：\")\n",
    "print(\"IDs:\", search_results['ids'])\n",
    "print(\"Scores:\", search_results['distances'])\n",
    "print(\"Documents:\", search_results['documents'])\n",
    "\n",
    "# 10. 使用 LLM 生成答案\n",
    "# 3. 初始化语言模型\n",
    "llm = Tongyi(\n",
    "    model='qwen-plus',  # 替换为您使用的 Tongyi 模型名称\n",
    "    top_p=0.9,\n",
    "    temperature=0.9,\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\")\n",
    ")\n",
    "\n",
    "# 将搜索结果的文档内容合并为上下文\n",
    "context = \"\\n\".join(search_results['documents'][0])\n",
    "\n",
    "# 构建提示（Prompt）\n",
    "prompt = f\"基于以下内容回答问题：\\n{context}\\n\\n问题：{query}\\n\\n答案：\"\n",
    "\n",
    "# 使用 LLM 生成答案\n",
    "answer = llm(prompt)\n",
    "print(\"\\nLLM 生成的答案：\")\n",
    "print(answer)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from langchain.indexes import VectorstoreIndexCreator\n",
    "from langchain.document_loaders import TextLoader\n",
    "from langchain.vectorstores import Chroma\n",
    "from langchain.llms import Tongyi  # 使用通义的语言模型\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "\n",
    "# 1. 初始化嵌入模型\n",
    "embedding = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n",
    "# 2. 加载文档\n",
    "document_path = '/root/autodl-tmp/lizhenping/langchain_tutorial/LangChain_CookBook/data/市场分析报告.txt'\n",
    "loader = TextLoader(document_path, encoding='utf-8')\n",
    "documents = loader.load()\n",
    "\n",
    "# 3. 创建向量存储索引\n",
    "persist_directory = \"ch16_db\"  # 指定向量存储的持久化目录\n",
    "collection_name = \"products\"   # 指定集合名称\n",
    "\n",
    "vectorstore = Chroma(\n",
    "    persist_directory=persist_directory,\n",
    "    embedding_function=embedding,\n",
    "    collection_name=collection_name\n",
    ")\n",
    "\n",
    "# 如果需要重新创建索引，可以先清空现有的集合\n",
    "# vectorstore._collection.delete()\n",
    "\n",
    "# 使用 VectorstoreIndexCreator 创建索引并添加到向量存储中\n",
    "# 2. 创建向量存储索引\n",
    "index_creator = VectorstoreIndexCreator(\n",
    "    vectorstore_cls=Chroma,\n",
    "    embedding=embedding,  # 替换为您使用的嵌入模型实例\n",
    ")\n",
    "index = index_creator.from_loaders([loader])\n",
    "\n",
    "# 4. 获取底层的向量存储对象\n",
    "vectorstore = index.vectorstore\n",
    "\n",
    "# 5. 查询 Vectorstore 中的向量信息\n",
    "# 获取所有向量的 IDs\n",
    "all_ids = vectorstore._collection.get()['ids']\n",
    "print(\"所有向量的 IDs：\")\n",
    "print(all_ids)\n",
    "\n",
    "# 6. 根据 ID 获取向量和元数据（Read）\n",
    "result = vectorstore._collection.get(ids=[all_ids[0]])\n",
    "print(\"\\n获取指定 ID 的向量和元数据：\")\n",
    "print(\"IDs:\", result['ids'])\n",
    "print(\"Embeddings:\", result['embeddings'])\n",
    "print(\"Metadatas:\", result['metadatas'])\n",
    "print(\"Documents:\", result['documents'])\n",
    "\n",
    "# 7. 更新向量的元数据（Update）\n",
    "new_metadata = {\"source\": \"updated_source.txt\"}\n",
    "vectorstore._collection.update(ids=[all_ids[0]], metadatas=[new_metadata])\n",
    "print(\"\\n更新后的元数据：\")\n",
    "updated_result = vectorstore._collection.get(ids=[all_ids[0]])\n",
    "print(\"Metadatas:\", updated_result['metadatas'])\n",
    "\n",
    "# 8. 添加新的向量（Create）\n",
    "new_document = \"这是一个新的文档内容，用于测试添加操作。\"\n",
    "new_embedding = embedding.embed_documents([new_document])[0]\n",
    "new_id = \"new_doc_id\"\n",
    "new_metadata = {\"source\": \"new_document.txt\"}\n",
    "vectorstore._collection.add(\n",
    "    ids=[new_id],\n",
    "    embeddings=[new_embedding],\n",
    "    documents=[new_document],\n",
    "    metadatas=[new_metadata]\n",
    ")\n",
    "print(\"\\n添加新向量后的所有 IDs：\")\n",
    "print(vectorstore._collection.get()['ids'])\n",
    "\n",
    "# 9. 删除指定的向量（Delete）\n",
    "vectorstore._collection.delete(ids=[all_ids[0]])\n",
    "print(\"\\n删除后的所有向量 IDs：\")\n",
    "print(vectorstore._collection.get()['ids'])\n",
    "\n",
    "# 10. 执行相似性搜索\n",
    "query = \"请提供市场分析的摘要。\"\n",
    "query_embedding = embedding.embed_query(query)\n",
    "search_results = vectorstore._collection.query(\n",
    "    query_embeddings=[query_embedding],\n",
    "    n_results=2  # 返回最相似的 2 个结果\n",
    ")\n",
    "print(\"\\n相似性搜索结果：\")\n",
    "print(\"IDs:\", search_results['ids'])\n",
    "print(\"Scores:\", search_results['distances'])\n",
    "print(\"Documents:\", search_results['documents'])\n",
    "\n",
    "# 11. 使用 LLM 生成答案\n",
    "llm = Tongyi(\n",
    "    model='qwen-plus',  # 替换为您使用的 Tongyi 模型名称\n",
    "    top_p=0.9,\n",
    "    temperature=0.9,\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\")\n",
    ")\n",
    "\n",
    "# 将搜索结果的文档内容合并为上下文\n",
    "context = \"\\n\".join(search_results['documents'][0])\n",
    "\n",
    "prompt = f\"基于以下内容回答问题：\\n{context}\\n\\n问题：{query}\\n\\n答案：\"\n",
    "\n",
    "# 使用 LLM 生成答案\n",
    "answer = llm(prompt)\n",
    "print(\"\\nLLM 生成的答案：\")\n",
    "print(answer)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from langchain.vectorstores import Chroma\n",
    "from langchain.indexes.vectorstore import VectorStoreIndexWrapper  # 正确的导入路径\n",
    "from langchain.document_loaders import TextLoader\n",
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "from langchain.llms import Tongyi  # 使用通义的语言模型\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "\n",
    "# 1. 初始化嵌入模型\n",
    "embedding = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n",
    "# 2. 加载文档\n",
    "document_path = '/root/autodl-tmp/lizhenping/langchain_tutorial/LangChain_CookBook/data/市场分析报告.txt'\n",
    "loader = TextLoader(document_path, encoding='utf-8')\n",
    "documents = loader.load()\n",
    "\n",
    "# 3. 拆分文档为段落\n",
    "text_splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=1000,\n",
    "    chunk_overlap=200\n",
    ")\n",
    "texts = text_splitter.split_documents(documents)\n",
    "\n",
    "# 4. 初始化向量存储（Chroma）\n",
    "persist_directory = \"ch16_db\"\n",
    "collection_name = \"products\"\n",
    "vectorstore = Chroma(\n",
    "    persist_directory=persist_directory,\n",
    "    embedding_function=embedding,\n",
    "    collection_name=collection_name\n",
    ")\n",
    "\n",
    "# 5. 将文本添加到向量存储中并生成嵌入\n",
    "vectorstore.add_documents(texts)\n",
    "\n",
    "# 6. 保存向量存储到磁盘\n",
    "vectorstore.persist()\n",
    "\n",
    "# 7. 使用 VectorStoreIndexWrapper 包装向量存储\n",
    "index = VectorStoreIndexWrapper(vectorstore=vectorstore)\n",
    "\n",
    "# 8. 初始化语言模型\n",
    "llm = Tongyi(\n",
    "    model='qwen-plus',\n",
    "    top_p=0.9,\n",
    "    temperature=0.9,\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\")\n",
    ")\n",
    "\n",
    "# 9. 执行查询并生成答案\n",
    "query = \"当前的市场趋势是什么？\"\n",
    "answer = index.query(query, llm=llm)\n",
    "\n",
    "print(\"\\n生成的答案：\")\n",
    "print(answer)\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "chatchat",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
